﻿using FPSO.HMI.Controls;
using FPSO.Models.Constant;
using FPSO.Services;
using FPSO.Services.Impl;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Threading;

namespace FPSO.HMI.Views.Dialog
{
    /// <summary>
    /// RealDataMonitorDialog.xaml 的交互逻辑
    /// </summary>
    public partial class RealDataMonitorDialog : Window
    {
        private DispatcherTimer ReadFileTimer;
        private DispatcherTimer CalcTimer;
        private string[] dataFiles = null;
        // 临时缓存的一个文件数据
        private Dictionary<string, Dictionary<string, double>> tempData = null;
        // 当前读取文件的索引
        private int fileIndex = 0;

        public RealDataMonitorDialog()
        {
            InitializeComponent();
            // 配置图表
            InitChart();
            // 计时器用来读取文件
            ReadFileTimer = new DispatcherTimer();
            ReadFileTimer.Interval = TimeSpan.FromSeconds(5);
            ReadFileTimer.Tick += ReadFile_Tick;
            ReadFileTimer.Start();

            // 计时器用来计算并添加数据到图表
            CalcTimer = new DispatcherTimer();
            CalcTimer.Interval = TimeSpan.FromSeconds(5);
            CalcTimer.Tick += Calc_Tick;
            CalcTimer.Start();
        }

		/// <summary>
		/// 计时器用来读取文件数据（当上一个文件使用完毕时）
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private async void ReadFile_Tick(object sender, EventArgs e)
        {
            // tempData为null时代表未读取文件或上个文件使用完被清理掉了，此时进行新文件的读取
            if (tempData == null)
            {
                tempData = await ReadDataByFilePathAsync(dataFiles[fileIndex]);
            }
        }

        /// <summary>
        /// 计时器用来计算并添加数据到图表
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Calc_Tick(object sender, EventArgs e)
        {
            // tempData不为null时代表有数据可用，则进行正常的计算流程
            if (tempData != null)
            {
                Dispatcher.Invoke(() =>
                {
                    foreach (var outerKey in tempData.Keys)
                    {
                        // 获取循环行数据
                        Dictionary<string, double> item = tempData[outerKey];
                        //Debug 获取文件中的数据 item["标签名"]
                        // 真实吃水数据
						try
						{
							double Tmp = item["SHIP.REAL_MIDP_DRAFT"] * TankConstant.TANKLEVEL_PARAM;
							double Tms = item["SHIP.REAL_MIDS_DRAFT"] * TankConstant.TANKLEVEL_PARAM;
							double realDraft = (Tmp + Tms) / 2;
							// 液位高等数据
							//double heighLevel = item[""];
							//Debug 计算流程

							// 往图表添加数据 AddDraftData(真实吃水, 计算吃水);
							AddDraftData(realDraft, 12.5);

						}
						catch(Exception ex) 
						{
							continue;
						}
					}
                    // 使用完当前数据清理缓存
                    tempData = null;
                    // 增加索引，让定时器进行下一文件的读取
                    fileIndex++;
                });
            }
        }


        private void InitChart()
        {
            // 吃水图表
            draft.SetCurve("Real", null, Colors.DodgerBlue);
            draft.SetCurve("Calc", null, Colors.DarkOrange);

        }

        /// <summary>
        /// 添加吃水数据
        /// </summary>
        /// <param name="real">真实数据</param>
        /// <param name="calc">计算数据</param>
        public void AddDraftData(double real, double calc)
        {
            this.Dispatcher.Invoke(new Action(() =>
            {
                draft.AddCurveData(new string[] { "Real", "Calc" }, new double[] { real, calc });
            }));
        }

        /// <summary>
        /// 提取船上数据
        /// </summary>
        /// <param name="input">txt路径</param>
        /// <returns></returns>
        static async Task<Dictionary<string, Dictionary<string, double>>> ReadDataByFilePathAsync(string path)
        {
            // 异步读取数据
            string input = await TaskUtils.ReadTxTContentAsync(path);

            // 使用 ConcurrentDictionary 以确保线程安全
            var result = new ConcurrentDictionary<string, Dictionary<string, double>>();

            // 用时间将输入文本分隔成块
            MatchCollection matches = new Regex(@"(\d{4}/\d{1,2}/\d{1,2}\s\d{1,2}:\d{2}:\d{2}):(.+?)(?=\d{4}/\d{1,2}/\d{1,2}\s\d{1,2}:\d{2}:\d{2}|$)", RegexOptions.Singleline).Matches(input);

            // 使用 Parallel.ForEach 来并行处理每个匹配项
            Parallel.ForEach(matches.Cast<Match>(), match =>
            {
                // 用:将时间和数据集分开
                string[] splitKV = match.Value.Split(new[] { ": " }, StringSplitOptions.None);
                // 时间作为result的key
                string time = splitKV[0];

                // 使用 StringBuilder 优化字符串拼接
                StringBuilder sb = new StringBuilder(splitKV[1]);
                // 用双斜杠将每个数据提取出来
                string[] item = sb.ToString().Split(new[] { " // " }, StringSplitOptions.RemoveEmptyEntries);

                // 数据值
                Dictionary<string, double> fields = new Dictionary<string, double>();
                foreach (string temp_str in item)
                {
                    // 用最后一个空格索引分隔出名称和数值
                    int lastSpaceIndex = temp_str.LastIndexOf(' ');
                    if (lastSpaceIndex != -1)
                    {
                        string part1 = temp_str.Substring(0, lastSpaceIndex).Trim();
                        string part2 = temp_str.Substring(lastSpaceIndex + 1).Trim();
                        // 提取fields的key值
                        // Debug 对标签名做处理
                        string key = part1.Replace(" - 1 Level", "LEVEL")
                            .Replace(" - 2 Level", "LEVEL1");

                        // 提取并转换fields的value值
                        double value;
                        // 如果value转换失败，则替换值为0
                        if (double.TryParse(part2, out value))
                        {
                            // 添加到fields中
                            fields[key] = value;
                        }
                    }
                }

                // 将time和fields添加到result中
                result.TryAdd(time, fields);
            });

            // 将 ConcurrentDictionary 转换为普通的 Dictionary
            return new Dictionary<string, Dictionary<string, double>>(result);
        }

        private void WindowMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                DragMove();
            }
        }

        private void Cancel_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }


    }
}
